from rest_framework.test import APITestCase, APIClient
from .models import SysUser, SysRole, SysConfig, SysMenu, SysRoleMenu, SysUserRole

# 用户登录测试
class UserLoginTest(APITestCase):
    def setUp(self):
        # 创建测试用户
        self.user = SysUser.objects.create_user(
            username='testuser',
            email='test@example.com',
            password='testpassword'
        )
        self.user.is_active = True
        self.user.save()
        
        # 设置客户端
        self.client = APIClient()
    
    def test_user_creation(self):
        """测试用户创建"""
        # 验证用户是否正确创建
        user = SysUser.objects.get(username='testuser')
        self.assertEqual(user.email, 'test@example.com')
        self.assertTrue(user.is_active)
        
    def test_user_authentication(self):
        """测试用户认证"""
        # 验证用户密码是否正确
        user = SysUser.objects.get(username='testuser')
        self.assertTrue(user.check_password('testpassword'))

# 角色管理测试
class RoleManagementTest(APITestCase):
    def setUp(self):
        # 创建管理员用户
        self.admin_user = SysUser.objects.create_user(
            username='admin',
            email='admin@example.com',
            password='adminpassword',
            is_staff=True
        )
        
        # 创建测试角色 - 匹配实际模型的字段
        self.role = SysRole.objects.create(
            name='测试角色',
            code='test_role',
            remark='测试角色备注'
        )
        
        # 设置客户端并登录
        self.client = APIClient()
        self.client.force_authenticate(user=self.admin_user)
    
    # 简化测试，只测试数据库操作    
    def test_role_creation(self):
        """测试角色创建"""
        # 验证角色是否正确创建
        role = SysRole.objects.get(code='test_role')
        self.assertEqual(role.name, '测试角色')
        self.assertEqual(role.remark, '测试角色备注')
        
    def test_role_update(self):
        """测试角色更新"""
        # 更新角色
        self.role.name = '更新的角色名'
        self.role.save()
        
        # 验证更新是否成功
        updated_role = SysRole.objects.get(id=self.role.id)
        self.assertEqual(updated_role.name, '更新的角色名')

# 菜单管理测试
class MenuManagementTest(APITestCase):
    def setUp(self):
        # 创建管理员用户
        self.admin_user = SysUser.objects.create_user(
            username='admin',
            email='admin@example.com',
            password='adminpassword',
            is_staff=True
        )
        
        # 创建父菜单
        self.parent_menu = SysMenu.objects.create(
            name='系统管理',
            icon='setting',
            path='/system',
            component='Layout',
            menu_type='M',  # 目录类型
            order_num=1
        )
        
        # 创建子菜单
        self.child_menu = SysMenu.objects.create(
            name='用户管理',
            icon='user',
            parent_id=self.parent_menu.id,
            path='user',
            component='system/user/index',
            menu_type='C',  # 菜单类型
            order_num=1,
            api_path='system/user'
        )
        
        # 创建按钮权限
        self.button_menu = SysMenu.objects.create(
            name='用户新增',
            parent_id=self.child_menu.id,
            menu_type='F',  # 按钮类型
            order_num=1,
            api_path='system/user/create'
        )
        
        # 创建角色并分配菜单权限
        self.role = SysRole.objects.create(
            name='测试角色',
            code='test_role',
            remark='测试角色备注'
        )
        
        # 角色分配菜单权限
        self.role_menu = SysRoleMenu.objects.create(
            role=self.role,
            menu=self.child_menu
        )
        
        # 设置客户端并登录
        self.client = APIClient()
        self.client.force_authenticate(user=self.admin_user)
    
    def test_menu_creation(self):
        """测试菜单创建"""
        # 验证菜单是否正确创建
        parent_menu = SysMenu.objects.get(name='系统管理')
        self.assertEqual(parent_menu.menu_type, 'M')
        self.assertEqual(parent_menu.path, '/system')
        
        child_menu = SysMenu.objects.get(name='用户管理')
        self.assertEqual(child_menu.parent_id, parent_menu.id)
        self.assertEqual(child_menu.menu_type, 'C')
        
        button_menu = SysMenu.objects.get(name='用户新增')
        self.assertEqual(button_menu.parent_id, child_menu.id)
        self.assertEqual(button_menu.menu_type, 'F')
    
    def test_menu_hierarchy(self):
        """测试菜单层级关系"""
        # 验证层级关系
        self.assertEqual(self.child_menu.parent_id, self.parent_menu.id)
        self.assertEqual(self.button_menu.parent_id, self.child_menu.id)
        
    def test_role_menu_assignment(self):
        """测试角色菜单分配"""
        # 验证角色菜单分配是否正确
        role_menu = SysRoleMenu.objects.get(role=self.role, menu=self.child_menu)
        self.assertIsNotNone(role_menu)
        self.assertEqual(role_menu.role, self.role)
        self.assertEqual(role_menu.menu, self.child_menu)
        
    def test_show_urls(self):
        """测试获取URL路径列表"""
        # 为测试直接禁用权限检查
        from system.views import MenuView
        original_permission_classes = MenuView.permission_classes
        MenuView.permission_classes = []
        
        try:
            # 调用show_urls接口
            response = self.client.get('/system/menu/show_urls/')
            
            # 验证响应状态码
            self.assertEqual(response.status_code, 200)
            
            # 验证响应数据结构
            self.assertIn('urls', response.data)
            self.assertIn('configured_urls', response.data)
            
            # 验证已配置的URL路径是否包含测试数据中的API路径
            configured_urls = response.data['configured_urls']
            # 检查是否包含我们在测试中设置的API路径
            self.assertIn('system/user', configured_urls)
        
        finally:
            # 恢复原始权限设置
            MenuView.permission_classes = original_permission_classes

# 配置管理测试
class ConfigManagementTest(APITestCase):
    def setUp(self):
        # 创建管理员用户
        self.admin_user = SysUser.objects.create_user(
            username='admin',
            email='admin@example.com',
            password='adminpassword',
            is_staff=True
        )
        
        # 创建测试配置
        self.config = SysConfig.objects.create(
            name='测试配置',
            json_value={'value': 'test_value'},
            remark='测试配置备注'
        )
        
        # 设置客户端并登录
        self.client = APIClient()
        self.client.force_authenticate(user=self.admin_user)
        
    def test_config_value_update(self):
        """测试更新配置值"""
        # 由于没有实际的配置API端点，我们直接更新数据库
        self.config.json_value = {'value': 'updated_value'}
        self.config.save()
        
        # 验证配置值是否正确更新
        updated_config = SysConfig.objects.get(name='测试配置')
        self.assertEqual(updated_config.json_value['value'], 'updated_value')
